/**
 *  
 */
global with sharing class Callidus_CommonUtilG 
{
    
    //This code is common to all the users in the organization.
    /**
     *  This class does not use "Sharing" keyword. Below are the reason
     *  Plan Admin will be the Owner of all the Data Source records, as the Data Source object is set to private.
     *  The below functionality is used to the send Acceptance Mail along with attachments to the respective Users and Plan Admin.
     *
     *  The below method bypasses the sharing rules by querying the Config(Callidus_Plan_Access_Control__c) object and check whether the current user has been granted by the Admin to bypass the sharing rules..The below method bypasses the sharing rules by querying the Config(Callidus_Plan_Access_Control__c) object and check whether the current user has been granted by the Admin to bypass the sharing rules.
     *  It uses OWASP ESAPI implementation for force.com to bypass the sharing rules.             
     */
    WebService static String updateStatus(String salesContractName)
    {  
        Schema.DescribeSobjectResult dsr = Sales_Contract__c.sObjectType.getDescribe();
        Schema.DescribeFieldResult dfrName = Sales_Contract__c.Name.getDescribe();
        Schema.DescribeFieldResult dfrStatus = Sales_Contract__c.Status__c.getDescribe();
        Schema.DescribeFieldResult dfrDateAccepted = Sales_Contract__c.DateAccepted__c.getDescribe();
        
        if(dsr.isAccessible() && dsr.isUpdateable() && dfrName.isAccessible() && dfrStatus.isAccessible() && dfrStatus.isUpdateable() && dfrDateAccepted.isAccessible() && dfrDateAccepted.isUpdateable())
        {       
            Sales_Contract__c[] sc = [SELECT Id, FirstName__c, LastName__c, AttachmentID__c, AttachmentIDVals__c, Accepted_Documents__c, Status__c, Name, DateAccepted__c, UserID__c, OwnerId, Email_Notification_1__c, Email_Notification_2__c, Email_Notification_3__c, Can_Accept_Plan__c from Sales_Contract__c s where s.Name = :salesContractName];
            if(sc.size() == 0)
            {
               return 'Sales Contract Id does not exist';
            }
            try{
                if(sc[0]!= null)
                {
                    Callidus_Plan_Access_Control__c[] cpacList = [select Is_Access_Allowed__c from Callidus_Plan_Access_Control__c where Participant__c = :UserInfo.getUserId()];
                    if(cpacList.size() > 0)
                    {
                        if(cpacList[0].Is_Access_Allowed__c == true)
                        {
                    
                            String[] attachmentIdList = sc[0].AttachmentIDVals__c.split(',');
                            //Attachment[] queryAttachment = [select Body, Id, Name, ContentType from Attachment where id in :attachmentIdList];
                            
                            String substituteVal = '(';
                            for(String v: attachmentIdList)
                            {
                                substituteVal += '\''+v+'\',';
                            }
                            substituteVal = substituteVal.substring(0, (substituteVal.length() - 1));
                            substituteVal += ')';
                            
                            ESAPI.accessController().setSharingMode(SFDCAccessController.SharingMode.WITHOUT);
                            //fetchAsUser method has the code that checks whether the current User has been granted by the Admin to bypass the sharing rules.  
                            List<SObject> sObjectList = ESAPI.accessController().fetchAsUser('select Body, Id, Name, ContentType from Attachment where id in '+substituteVal);
                            Attachment[] queryAttachment = sObjectList;                                             
                            
                            String attachmentNamesValue = '';
                            Messaging.EmailFileAttachment[] allAttachments = new  Messaging.EmailFileAttachment[queryAttachment.size()]; 
                            for(integer i=0;i<queryAttachment.size();i++)
                            {
                                Messaging.EmailFileAttachment fileAttachment = new Messaging.EmailFileAttachment();
                                fileAttachment.setBody(queryAttachment[i].Body);
                                fileAttachment.setFileName(queryAttachment[i].Name);
                                allAttachments[i] =  fileAttachment;
                                attachmentNamesValue += queryAttachment[i].Name+'; ';
                            }
                            attachmentNamesValue = attachmentNamesValue.substring(0, attachmentNamesValue.length() - 2);
                            
                            sc[0].Accepted_Documents__c = attachmentNamesValue;
                            sc[0].Status__c = 'Accepted';
                            sc[0].DateAccepted__c = Datetime.now();
                            update sc;
                            
//                            if(sc[0].Can_Accept_Plan__c == true)
  //                          {                  
                                
                                EmailTemplate e = [select Id,Name,Subject,body from EmailTemplate where name like :'Callidus_Plan_Document_Acceptance_Mail'];
                                                                    
                                Messaging.SingleEmailMessage[] mailList = new Messaging.SingleEmailMessage[]{};
            
                                Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();                 
                                mail.saveAsActivity = false;
	                            if(sc[0].Can_Accept_Plan__c == true)
	                            {                  
      	                        	mail.setFileAttachments(allAttachments);
	                            }
                                mail.setTargetObjectId(sc[0].UserId__c);
                                mail.setTemplateId(e.Id);
                                mail.setWhatId(sc[0].Id);
                                mail.setUseSignature(false);
                                mail.setSaveAsActivity(false);
                                mailList.add(mail);
            
                                mail = new Messaging.SingleEmailMessage();                  
                                mail.saveAsActivity = false;
	                            if(sc[0].Can_Accept_Plan__c == true)
	                            {                  
                                	mail.setFileAttachments(allAttachments);
	                            }
                                mail.setTargetObjectId(sc[0].OwnerId);
                                mail.setTemplateId(e.Id);
                                mail.setWhatId(sc[0].Id);
                                mail.setUseSignature(false);
                                mail.setSaveAsActivity(false);
                                mailList.add(mail);
                                
                                if(sc[0].Email_Notification_1__c != null)
                                {
                                    mail = new Messaging.SingleEmailMessage();                  
                                    mail.saveAsActivity = false;
                                    mail.setFileAttachments(allAttachments);
                                    mail.setTargetObjectId(sc[0].Email_Notification_1__c);
                                    mail.setTemplateId(e.Id);
                                    mail.setWhatId(sc[0].Id);
                                    mail.setUseSignature(false);
                                    mail.setSaveAsActivity(false);
                                    mailList.add(mail);
                                }
            
                                if(sc[0].Email_Notification_2__c != null)
                                {
                                    mail = new Messaging.SingleEmailMessage();                  
                                    mail.saveAsActivity = false;
                                    mail.setFileAttachments(allAttachments);
                                    mail.setTargetObjectId(sc[0].Email_Notification_2__c);
                                    mail.setTemplateId(e.Id);
                                    mail.setWhatId(sc[0].Id);
                                    mail.setUseSignature(false);
                                    mail.setSaveAsActivity(false);
                                    mailList.add(mail);
                                }
            
                                if(sc[0].Email_Notification_3__c != null)
                                {
                                    mail = new Messaging.SingleEmailMessage();                  
                                    mail.saveAsActivity = false;
                                    mail.setFileAttachments(allAttachments);
                                    mail.setTargetObjectId(sc[0].Email_Notification_3__c);
                                    mail.setTemplateId(e.Id);
                                    mail.setWhatId(sc[0].Id);
                                    mail.setUseSignature(false);
                                    mail.setSaveAsActivity(false);
                                    mailList.add(mail);
                                }
                                // Send the email
                                Messaging.sendEmail(mailList);
                          //  }                       
                        }
                    }
                }
           }
           catch(Exception e){return e.getMessage();}
           
        }
        return 'success';
    }
    
    Webservice static String savePlanSearchConfigurations(String isRoleEnabled, String isUserEnabled, String isStatusEnabled, String isGroupEnabled, String isDateEnabled)
    {
        SObject sobj = new Remote_IP_Address__c();
        DataAccessControlUtil dacu = new DataAccessControlUtil();
        Map<String, Schema.SObjectField> commonConfigSObjectFieldMap = dacu.getFieldMap(sObj);
            
        String[] roFields = new String[]{'Id', 'Is_Role_Shown__c'}; 
        Set<String> allowedROFields = dacu.getAccessibleFields(sObj, commonConfigSObjectFieldMap, roFields);
        String formSoql = '';                       
        if(!allowedROFields.isEmpty())
        {
            formSoql = 'Select ';
            for(String roField: allowedROFields)
            {
                formSoql += roField+', ';
            }
            formSoql = formSoql.substring(0, formSoql.length() - 2);
            formSoql += ' from Remote_IP_Address__c ';

            Remote_Ip_Address__c[] ripList = Database.query(formSoql);
            String message = '';
            if(ripList.size() > 0)
            {
                message = dacu.isUpdateableObjectByUser(sObj);
                if(message.equalsIgnoreCase('success'))
                {

                    //Note: Whenever a new Custom field has to be updated, add it to the below Set.
                    //Reason: The size of the below set will be compared with the size of the filtered set 
                    Set<String> fieldsToBeUpdatedList = new Set<String>{'Is_Role_Shown__c'};
                    
                    //Store the expected updated fields and their values
                    Map<String, Boolean> fieldsValMap = new Map<String, Boolean>();
                    fieldsValMap.put('Is_Role_Shown__c', (isRoleEnabled == 'yes'? true: false));
                    
                    //Filter the above list to get the fields that can be updated by the User. 
                    Set<String> filteredList = dacu.getFilteredUpdateableFields(commonConfigSObjectFieldMap, fieldsToBeUpdatedList);
                    sObj = ripList[0];
                    
                    //Enters only if the filteredList size is equivalent to the size of expected updateable fields List 
                    if(filteredList.size() == fieldsToBeUpdatedList.size())
                    {
                        for(String s: filteredList)
                        {
                            sObj.put(s, fieldsValMap.get(s));
                        }
                        
                        update sObj;
                    }
                }
                else
                    return message;     
            }
            else
            {

                message = dacu.isCreateableObjectByUser(sObj);
                if(message.equalsIgnoreCase('success'))
                {
                    Remote_IP_Address__c rip = new Remote_IP_Address__c();
                    sObj = rip;
                    
                    //Note: Whenever a new Custom field has to be created, add it to the below Set.
                    //Reason: The size of the below set will be compared with the size of the filtered set 
                    Set<String> fieldsToBeCreatedList = new Set<String>{'Is_Role_Shown__c'};
                    
                    //Store the expected inserted fields and their values
                    Map<String, Boolean> fieldsValMap = new Map<String, Boolean>();
                    fieldsValMap.put('Is_Role_Shown__c', (isRoleEnabled == 'yes'? true: false));
                    
                    //Filter the above list to get the fields that can be created by the User. 
                    Set<String> filteredList = dacu.getFilteredCreateableFields(commonConfigSObjectFieldMap, fieldsToBeCreatedList);
                    
                    //Enters only if the filteredList size is equivalent to the size of expected createable fields List 
                    if(filteredList.size() == fieldsToBeCreatedList.size())
                    {
                        for(String s: filteredList)
                        {
                            sObj.put(s, fieldsValMap.get(s));
                        }
                    
                        insert sObj;
                    }
                }
                else
                    return message;
            }
        }
        return 'success'; 
    }
    
    
}